package cc.android.testapp.cfg;

import android.util.Log;
import android.util.Pair;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import cc.android.testapp.util.CLog;
import cc.commons.util.reflect.FieldUtil;

public class ConfigVPaser {

    public static final HashMap<Class<?>, Function<String, Object>> mPasers = new HashMap<>();

    static {
        registerPaser((v) -> !v.isEmpty() && Boolean.parseBoolean(v), boolean.class, Boolean.class);
        registerPaser((v) -> v.isEmpty() ? 0 : Byte.parseByte(v), byte.class, Byte.class);
        registerPaser((v) -> v.isEmpty() ? 0 : Short.parseShort(v), short.class, Short.class);
        registerPaser((v) -> v.isEmpty() ? 0 : Integer.parseInt(v), char.class, Character.class);
        registerPaser((v) -> v.isEmpty() ? 0 : Integer.parseInt(v), int.class, Integer.class);
        registerPaser((v) -> v.isEmpty() ? 0 : Long.parseLong(v), long.class, Long.class);
        registerPaser((v) -> v.isEmpty() ? 0F : Float.parseFloat(v), float.class, Float.class);
        registerPaser((v) -> v.isEmpty() ? 0D : Double.parseDouble(v), double.class, Double.class);
        registerPaser((v) -> v, String.class);
    }

    public static void registerPaser(Function<String, Object> pPaser, Class<?>... pTypes) {
        for (Class<?> sClazz : pTypes) mPasers.put(sClazz, pPaser);
    }

    public static <T> T paser(Class<T> pType, String pValue) throws JSONException {
//        if (Map.class.isAssignableFrom(pType)) {
//            JSONObject tJson = new JSONObject(pValue);
//            HashMap<String,Object> tMap=new HashMap<>();
//            Map a;
//
//        }
//        pType.isPrimitive();
        Function<String, Object> t = mPasers.get(pType);
        if (t != null) {
            return (T) t.apply(pValue);
        }
        return null;
    }

    /**
     * 解析配置模块的注解
     *
     * @param pConfig 配置模块
     * @return
     */
    public static HashMap<Field, Pair<String, String>> resloveCfgAnno(ConfigHelper.IConfig pConfig) {
        HashMap<Field, Pair<String, String>> tAnnos = new HashMap<>();
        for (Field sField : pConfig.getClass().getDeclaredFields()) {
            CFG tAnno = sField.getAnnotation(CFG.class);
            if (tAnno == null) continue;
            String tKey = tAnno.key();
            if (tKey.isEmpty()) {
                String tName = sField.getName();
                if (tName.length() >= 2 && tName.charAt(0) == 'm' && Character.isUpperCase(tName.charAt(1))) {
                    tName = tName.substring(1);
                }
                int tUpCount = 0;
                StringBuilder tSBuilder = new StringBuilder();
                for (int i = 0; i < tName.length(); i++) {
                    char c = tName.charAt(i);
                    if (Character.isUpperCase(c)) {
                        if (i != 0) {
                            tSBuilder.append('_');
                        }
                        tSBuilder.append(Character.toLowerCase(c));
                        tUpCount++;
                    } else {
                        tSBuilder.append(c);
                    }
                }
                if (tUpCount == tName.length()) tKey = tName.toLowerCase(); // all up
                else tKey = tSBuilder.toString();
            }
            String tDef = tAnno.def();
            if (tDef.isEmpty()) {
                Object tObj = FieldUtil.getFieldValue(sField, pConfig);
                if (tObj != null) {
                    tDef = String.valueOf(tObj);
                }
            }
            tAnnos.put(sField, new Pair<>(tKey, tDef));
        }
        return tAnnos;
    }
}
